#include "utils/cxx-include.hpp"
#include "utils/core-module.hpp"
#include "core/random.hpp"

using namespace cas;

int main(int argc, char *argv[])
{
    LogSetTimePrinter(&DefaultTimePrinter); // activate time printer

    MersenneTwisterRNG<> mtRng(5489u);
    UniformRealRND uniRnd;
    uniRnd.setRng(std::make_shared<MersenneTwisterRNG<>>(mtRng));

    UniformInt64RND uniI64Rnd;
    uniI64Rnd.setParam(-2048, 2049);

    std::cout
        << std::setprecision(12)
        << "seed: 5489" << std::endl
        << "   mt: " << mtRng() << " == 14514284786278117030" << std::endl
        << "  uni: " << uniRnd() << " == 0.786820954868" << std::endl
        << "  uni: " << uniRnd() << " == 0.250480340688" << std::endl;

    mtRng.setSeed(RNG<>::DefaultSeed);

    std::cout
        << "seed: " << RNG<uint64_t>::DefaultSeed << std::endl
        << "   mt: " << mtRng() << " == 6011348917613078650" << std::endl
        << "  uni: " << uniRnd() << " == 0.250480340688" << std::endl
        << "  uni: " << uniRnd() << " == 0.946667800961" << std::endl;

    uniRnd.setParam(-100.0, 100.0);
    std::cout
        << "  uni: " << uniRnd() << " == -96.1457883608" << std::endl
        << "  uni: " << uniRnd() << " == -19.0195710368" << std::endl
        << "  uni: " << uniRnd() << " == -49.7364364144" << std::endl;

    int64_t sum = 0;
    for (int i = 0; i < 1000000; i++)
    {
        sum += uniI64Rnd();
    }

    std::cout
        << "  i64: " << uniI64Rnd() << " == -400" << std::endl
        << "  sum: " << sum << " == 291784 (avg +0.29)" << std::endl;

    return 0;
}